package com.boring.tests;

public class Main {

    public static void main(String[] args) {

        stringTest();

        int test = test();
        System.out.println(test); //3

        testInt();
        System.out.println("-----------------");

        //String具有不可变性 char可变
        StringExer se = new StringExer();
        se.test(se.str,se.ch);
        System.out.println(se.str);
        System.out.println(se.ch);

		//理解上面
		testChangeString();

    }

    /**
     * 字符串的一些测试跟理解
     * 堆中的字符串常量池不会存储相同的字符串
     */
    public static void stringTest(){

        //String 是 final类 (不可修改)
        //str 仅仅是一个引用对象，它指向一个字符串对象“abc”.
        //第二行代码的含义是让 str 重新指向了一个新的字符串“bcd”对象，而“abc”对象并没有任何改变，只不过该对象已经成为一个不可及对象罢了
        String str = "abc" ;
        str = "cde";

        System.out.println("--------------------------------");

        //对于字符串常量，如果内容相同，Java 认为它们代表同一个 String 对象。而用关键字 new 调用构造器，总是会创建一个新的对象，无论内容是否相同。
        String s1 = "abc" ;
        String s2 ="abc";
        //s1="hello"; 如果这行代码放开 那么s2指向abc 然后会看常量池有无hello这个字符串没有就新建一个让后让s1去指向，并不会改变s2 则s1==s2 就是false了
        System.out.println(s1 == s2); //true    字符串有不可变性,且在字符串常量池中相同的字符串只会存储一次，所以都是他们都是同个指向 true

        String s3 = "aaa";
        String s4 = new String("aaa");
        System.out.println(s3 == s4); //false

        System.out.println("--------------------------------");

        //因为字符串有不可变性，所以你修改本质上就是新建了一个 原先s5 s6都指向cbd 这时候s6+ahhah 所以s6指向了新的字符串，s5不改变
        String s5 = "cba";
        String s6 = "cba";
        s6+="ahhah"; //修改

        System.out.println(s5);  //cba
        System.out.println(s6);  //cbaahhah

        System.out.println("--------------------------------");


        //字符串具有不可变性 ,其实就是在字符串常量池中生成了一个hgf替换h字符得到的mgf对象然后s8去指向
        String s7 = "hgf";
        String s8 = s7.replace("h","m");
        System.out.println(s7);     //hgf
        System.out.println(s8);     //mgf
        //s7 ==s8?  false


        //如果从运行结果来解释，那么"+" 和 StringBuilder.append是完全等效的
        //String的 + 运算符本质是new StringBuilder在调用它的append方法把字符串拼接在一起
        //所以如果使用+来 循环 拼接字符串的话很消耗性能，应该在循环外就new 一个StringBuilder 循环内append即可
        String s10 = "hahahaha";
        s10 +="baibaibai";  //反编译后结果为s10 = (new StringBuilder(String.valueOf(s10))).append("baibaibai");

    }


    /**
     * 方法的结束标志是什么 return 或 throw 异常
     *
     * 测试try catch 每个方法都一定会有一个return 用来结束方法(如果没throw) 如果是void 默认是 return; 可写也可不写
     * 所以这里不管出错不出错都是 3 因为 finally 一定会执行
     * 如果没finally就看出错还是不出错
     * @return
     */
    private static int test(){
        try{
            return 1;
        }catch (Exception e){
            return 2;
        }finally {
            return 3;
        }

    }

    public static void testInt(){
        int a = 2147483647;
        System.out.println(a);
    }


    //String具有不可变性 char是可变的，所以在方法内这个str为changGood方法运行完后生命周期结束对外面本身的str是没影响的
    //char数组就会随之改变，因为char数组是个引用而且也不是不可变的
    static class StringExer{

            String str = new String("good");
            char[] ch = {'t','e','s','t'};

            public void test(String str,char[] ch){
                str = "changeGood";
                ch[0] = 'b';

                System.out.println(str);    //changGood 方法结束后是good 因为final不可改变性
                System.out.println(ch);     //best 且方法结束后依旧是best
            }


    }
	
	
	//用这个例子理解上面的StringExer
	public static void testChangeString(){
        String str1 = "aaa";
        char[] chars ={'t','e','s','t'};
        changeString(str1,chars);
        System.out.println(str1); //aaa
        System.out.println(chars); // best

    }

	//在这里面str做了修改没return出去所以还是aaa，如果return出去了str1也接收了返回值就是bbb了，因为string不可变性但如果返回了bbb且接收了对于string来说是个新的对象了肯定就变了，就相当于str1="bbb"
    private static void changeString(String str,char[] chars){
        str = "bbb";
        chars[0] = 'b';
        System.out.println(str); //bbb
    }



}
